package com.feicheng.service.impl;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.JSONValidator;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.feicheng.common.constant.Constant;
import com.feicheng.common.exception.SystemException;
import com.feicheng.common.message.SystemMessage;
import com.feicheng.common.result.ResultInfo;
import com.feicheng.persistence.entity.Permission;
import com.feicheng.persistence.entity.Role;
import com.feicheng.persistence.entity.RolePermission;
import com.feicheng.persistence.entity.User;
import com.feicheng.persistence.entity.UserRole;
import com.feicheng.persistence.service.IPermissionService;
import com.feicheng.persistence.service.IRolePermissionService;
import com.feicheng.persistence.service.IRoleService;
import com.feicheng.persistence.service.IUserRoleService;
import com.feicheng.persistence.service.IUserService;
import com.feicheng.service.BaseService;
import com.feicheng.service.IFSystemService;

/**
 * 管理平台系统业务逻辑
 * @see com.feicheng.service.IFSystemService
 */
@Service
public class FAdminSystemServiceImpl extends BaseService implements IFSystemService {

    @Autowired
    IUserService iUserService;

    @Autowired
    IRoleService iRoleService;

    @Autowired
    IPermissionService iPermissionService;

    @Autowired
    IUserRoleService iUserRoleService;

    @Autowired
    IRolePermissionService iRolePermissionService;

    @Autowired
    SystemMessage systemMessage;

    /**
     * @see com.feicheng.service.IFSystemService#selectUser(Integer, Integer, String, String, String)
     */
    @Override
    public ResultInfo selectUser(Integer currentPage, Integer pageSize, String account, String tel, String secId, Integer storeId) {

        // 构建查询条件
        QueryWrapper<User> userWrapper = new QueryWrapper<User>();
        // 如果账号不是空把账号加入查询的条件中
        if (StringUtils.hasLength(account)) {
            userWrapper.like(Constant.ENTITY.USER.ACCOUNT, account);
        }
        // 如果电话号码不是空把电话号码加入到查询的条件中
        if (StringUtils.hasLength(tel)) {
            userWrapper.like(Constant.ENTITY.USER.TEL, tel);
        }
        // 如果身份证号码不是空把身份证号码加入到查询条件中
        if (StringUtils.hasLength(secId)) {
            userWrapper.like(Constant.ENTITY.USER.SEC_ID, secId);
        }

        // 创建分页查询
        IPage<User> pageInfo = new Page<User>(currentPage, pageSize);
        // 返回查询结果
        return ResultInfo.success(iUserService.page(pageInfo, userWrapper));

    }

    @Override
    public ResultInfo selectUserByAccount(String account) {

        QueryWrapper<User> userQueryWrapper = new QueryWrapper<>();

        if (null != account) {
            userQueryWrapper.eq(Constant.ENTITY.USER.ACCOUNT,account);
        }

        return ResultInfo.success(iUserService.list(userQueryWrapper));

    }

    /**
     * @see com.feicheng.service.IFSystemService#selectUserById(Integer)
     */
    @Override
    public ResultInfo selectUserById(Integer userId) {
        // 校验用户ID
        if (null == userId) {
            throw new SystemException(systemMessage.getE01());
        }

        // 根据主键id查询
        User user = iUserService.getById(userId);

        // 构建查询条件
        QueryWrapper<UserRole> userRoleWrapper = new QueryWrapper<UserRole>();
        userRoleWrapper.eq(Constant.ENTITY.USER.USER_ID, userId);

        // 执行查询
        List<UserRole> userRoles = iUserRoleService.list(userRoleWrapper);

        // 将取得取得的角色ID保存到角色ID集合中
        Set<Integer> roleIds = new HashSet<Integer>();
        for (UserRole ur : userRoles) {
            roleIds.add(ur.getRoleId());
        }

        // 将取得的结果保存到返回结果中
        JSONObject result = new JSONObject();
        result.put(Constant.RESULT.USER.USER, user);

        if (roleIds.size() > 0) {

            /* 构建角色查询 */
            QueryWrapper<Role> roleWrapper = new QueryWrapper<Role>();
            roleWrapper.in(Constant.ENTITY.ROLE.ROLE_ID, roleIds);
            List<Role> roles = iRoleService.list(roleWrapper);
            result.put(Constant.RESULT.ROLE.ROLES, roles);

            // 构建角色ID查询条件
            QueryWrapper<RolePermission> rolePermissionWrapper =
                    new QueryWrapper<RolePermission>();
            rolePermissionWrapper.in(Constant.ENTITY.ROLE.ROLE_ID, roleIds);

            // 执行权限ID查询
            List<RolePermission> rolePermissions =
                    iRolePermissionService.list(rolePermissionWrapper);

            // 将取得的权限ID保存到权限ID集合中
            Set<Integer> permissionIds = new HashSet<Integer>();
            for (RolePermission rp : rolePermissions) {
                permissionIds.add(rp.getPermissionId());
            }

            if (permissionIds.size() > 0) {
                QueryWrapper<Permission> permissionWrapper = new QueryWrapper<Permission>();
                if (!permissionIds.isEmpty()) {
                    permissionWrapper.in(Constant.ENTITY.PERMISSION.PERMISSION_ID, permissionIds);
                }
                permissionWrapper.orderByAsc(Constant.ENTITY.PERMISSION.P_ID);

                // 执行权限查询
                List<Permission> permissions = iPermissionService.list(permissionWrapper);

                result.put(Constant.RESULT.PERMISSION.PERMISSIONS, permissions);
            }
        }



        // 返回查询到的用户信息
        return ResultInfo.success(result);
    }

    /**
     * @see com.feicheng.service.IFSystemService#addUser(User, String) 
     */
    @Override
    @Transactional
    public ResultInfo addUser(User user, String roles) {

        /* 校验用户信息 */
        if (!StringUtils.hasLength(user.getAccount())
                || !StringUtils.hasLength(user.getPassword())
                || !StringUtils.hasLength(user.getTel())
                || !StringUtils.hasLength(user.getSecId())) {
            throw new SystemException(systemMessage.getE02());
        }

        /* 校验用户角色信息 */
        if (!StringUtils.hasLength(roles)) {
            throw new SystemException(systemMessage.getE03());
        }

        /* 设置用户信息完成新增 */
        user.setOpenId("");
        user.setCu(super.currentUser().getUserId());
        user.setUu(super.currentUser().getUserId());
        user.setCt(super.ct(true));
        user.setUt(super.ct());
        iUserService.save(user);

        /* 设置用户角色信息完成新增 */
        JSONArray rolesIdArray = JSONArray.parseArray(roles);
        List<UserRole> roleList = new ArrayList<UserRole>();
        for (int i = 0; i < rolesIdArray.size(); i++) {
            Integer roleId = Integer.parseInt((String) rolesIdArray.get(i));
            UserRole userRole = new UserRole();
            userRole.setUserId(user.getUserId());
            userRole.setRoleId(roleId);
            roleList.add(userRole);
        }
        iUserRoleService.saveBatch(roleList);

        // 返回执行结果
        return ResultInfo.success(user);
    }

    /**
     * @see com.feicheng.service.IFSystemService#updateUser(User, String) 
     */
    @Override
    @Transactional
    public ResultInfo updateUser(User user, String roles) {

        /* 校验用户主键 */
        if (null == user.getUserId()) {
            throw new SystemException(systemMessage.getE01());
        }
        
        user.setUu(super.currentUser().getUserId());
        user.setUt(super.ct(true));
        // 修改用户信息
        iUserService.updateById(user);

        /* 通过userId删除user和role的关联 */
        if (StringUtils.hasLength(roles)) {
            QueryWrapper<UserRole> removeWrapper = new QueryWrapper<UserRole>();
            removeWrapper.eq(Constant.ENTITY.USER.USER_ID, user.getUserId());
            iUserRoleService.remove(removeWrapper);

            // 新增user与role的关联
            JSONArray rolesIdArray = JSONArray.parseArray(roles);
            List<UserRole> roleList = new ArrayList<UserRole>();
            for (int i = 0; i < rolesIdArray.size(); i++) {
                Integer roleId = (Integer) rolesIdArray.get(i);
                UserRole userRole = new UserRole();
                userRole.setUserId(user.getUserId());
                userRole.setRoleId(roleId);
                roleList.add(userRole);
            }
            iUserRoleService.saveBatch(roleList);
        }

        // 返回更新结果
        return ResultInfo.success(user);
    }

    /**
     * @see com.feicheng.service.IFSystemService#deleteUser(Integer) 
     */
    @Override
    @Transactional
    public ResultInfo deleteUser(Integer userId) {
        /* 校验用户主键 */
        if (null == userId) {
            throw new SystemException(systemMessage.getE01());
        }

        /* 删除用户角色信息 */
        QueryWrapper<UserRole> deleteWrapper = new QueryWrapper<UserRole>();
        deleteWrapper.eq(Constant.ENTITY.USER.USER_ID, userId);
        iUserRoleService.remove(deleteWrapper);

        /* 删除用户信息 */
        iUserService.removeById(userId);

        // 返回删除结果
        return ResultInfo.success();
    }

    /**
     * @see com.feicheng.service.IFSystemService
     */
    @Override
    public ResultInfo selectRoles(String roleName, Boolean statu, Integer currentPage, Integer pageSize) {
        QueryWrapper<Role> roleQueryWapper = new QueryWrapper<Role>();

        if (StringUtils.hasLength(roleName)) {
            roleQueryWapper.like(Constant.ENTITY.ROLE.ROLE_NAME, roleName);
        }

        if (statu != null) {
            roleQueryWapper.eq(Constant.ENTITY.ROLE.STATU, statu);
        }

        IPage<Role> pageInfo = new Page<Role>(currentPage, pageSize);
        return ResultInfo.success(iRoleService.page(pageInfo, roleQueryWapper));
    }

    /**
     * @see com.feicheng.service.IFSystemService#allRoles(Boolean) 
     */
    @Override
    public ResultInfo allRoles(Boolean statu) {
        QueryWrapper<Role> roleQueryWapper = new QueryWrapper<Role>();
        roleQueryWapper.eq(Constant.ENTITY.ROLE.STATU, statu);
        return ResultInfo.success(iRoleService.list(roleQueryWapper));
    }

    /**
     * @see com.feicheng.service.IFSystemService#getRoleById(Integer) 
     */
    @Override
    public ResultInfo getRoleById(Integer roleId) {
        if (null == roleId) {
            throw new SystemException(systemMessage.getE04());
        }

        Role role = iRoleService.getById(roleId);

        if (null == role) {
            throw new SystemException(systemMessage.getE07());
        }

        JSONObject result = new JSONObject();
        result.put(Constant.RESULT.ROLE.ROLE, role);

        QueryWrapper<RolePermission> rpWrapper = new QueryWrapper<RolePermission>();
        rpWrapper.eq(Constant.ENTITY.ROLE.ROLE_ID, roleId);
        List<RolePermission> rpList = iRolePermissionService.list(rpWrapper);
        if (null != rpList && !rpList.isEmpty()) {
            List<Integer> permissionIds = new ArrayList<Integer>();
            for (RolePermission rp : rpList) {
                permissionIds.add(rp.getPermissionId());
            }
            result.put(Constant.RESULT.PERMISSION.PERMISSIONS, permissionIds);
        }

        return ResultInfo.success(result);
    }

    /**
     * @see com.feicheng.service.IFSystemService#addRole(Role, String) 
     */
    @Override
    @Transactional
    public ResultInfo addRole(Role role, String permissions) {
        if (null != role.getRoleId()) {
            throw new SystemException(systemMessage.getE05());
        }
        
        role.setCu(super.currentUser().getUserId());
        role.setUu(super.currentUser().getUserId());
        role.setCt(super.ct(true));
        role.setUt(super.ct());
        role.setStatu(true);
        iRoleService.save(role);

        if (null == role.getRoleId()) {
            throw new SystemException(systemMessage.getE06());
        }

        if (JSONArray.isValidArray(permissions)) {
            JSONArray permissionIds = JSON.parseArray(permissions);
            if (!permissionIds.isEmpty()) {
                QueryWrapper<RolePermission> rpWrapper = new QueryWrapper<RolePermission>();
                rpWrapper.eq(Constant.ENTITY.ROLE.ROLE_ID, role.getRoleId());
                iRolePermissionService.remove(rpWrapper);
                List<RolePermission> batchList = new ArrayList<RolePermission>();
                for (Object permissionId : permissionIds) {
                    RolePermission rm = new RolePermission();
                    rm.setRoleId(role.getRoleId());
                    rm.setPermissionId((Integer) permissionId);
                    batchList.add(rm);
                }
                iRolePermissionService.saveBatch(batchList);
            }
        }

        return ResultInfo.success();
    }

    /**
     * @see com.feicheng.service.IFSystemService#updateRole(Role, String) 
     */
    @Override
    @Transactional
    public ResultInfo updateRole(Role role, String permissions) {
        if (null == role.getRoleId()) {
            throw new SystemException(systemMessage.getE04());
        }

        iRoleService.updateById(role);

        if (JSONValidator.from(permissions).validate()) {

            JSONArray permissionIds = JSON.parseArray(permissions);
            if (!permissionIds.isEmpty()) {
                QueryWrapper<RolePermission> rpWrapper = new QueryWrapper<RolePermission>();
                iRolePermissionService.remove(rpWrapper);

                List<RolePermission> batchList = new ArrayList<RolePermission>();
                for (Object permissionId : permissionIds) {
                    RolePermission rm = new RolePermission();
                    rm.setRoleId(role.getRoleId());
                    rm.setPermissionId((Integer) permissionId);
                    batchList.add(rm);
                }
                iRolePermissionService.saveBatch(batchList);
            }
        }

        return ResultInfo.success();
    }

    /**
     * @see com.feicheng.service.IFSystemService#deleteRole(Integer) 
     */
    @Override
    @Transactional
    public ResultInfo deleteRole(Integer roleId) {
        if (null == roleId) {
            throw new SystemException(systemMessage.getE04());
        }

        QueryWrapper<RolePermission> rpWrapper = new QueryWrapper<RolePermission>();
        rpWrapper.eq(Constant.ENTITY.ROLE.ROLE_ID, roleId);
        iRolePermissionService.remove(rpWrapper);
        iRoleService.removeById(roleId);
        return ResultInfo.success();
    }

    /**
     * @see com.feicheng.service.IFSystemService#getPermissions(String, String, Boolean, Integer, Integer, Integer) 
     */
    @Override
    public ResultInfo getPermissions(String name, String path, Boolean statu, Integer pId, Integer currentPage, Integer pageSize) {
        QueryWrapper<Permission> permissionQueryWapper = new QueryWrapper<Permission>();

        if (StringUtils.hasLength(name)) {
            permissionQueryWapper.like(Constant.ENTITY.PERMISSION.NAME, name);
        }

        if (StringUtils.hasLength(path)) {
            permissionQueryWapper.like(Constant.ENTITY.PERMISSION.PATH, path);
        }

        if (null != statu) {
            permissionQueryWapper.eq(Constant.ENTITY.PERMISSION.STATU, statu);
        }

        if (null != pId) {
            permissionQueryWapper.eq(Constant.ENTITY.PERMISSION.P_ID, pId);
        }

        IPage<Permission> pageInfo = new Page<Permission>(currentPage, pageSize);
        return ResultInfo.success(iPermissionService.page(pageInfo, permissionQueryWapper));
    }

    /**
     * @see com.feicheng.service.IFSystemService#allPermissions(Boolean, Integer) 
     */
    @Override
    public ResultInfo allPermissions(Boolean statu, Integer pId) {

        QueryWrapper<Permission> permissionQueryWrapper = new QueryWrapper<Permission>();
        if (null != statu) {
            permissionQueryWrapper.eq(Constant.ENTITY.PERMISSION.STATU, statu);
        }

        if (null != pId) {
            permissionQueryWrapper.eq(Constant.ENTITY.PERMISSION.P_ID, pId);
        }

        List<Permission> allList = iPermissionService.list(permissionQueryWrapper);
        List<Permission> result = new ArrayList<Permission>();
        Map<Integer, Permission> pMap = new HashMap<Integer, Permission>();
        for (Permission p : allList) {
            if (0 == p.getPId()) {
                pMap.put(p.getPermissionId(), p);
                result.add(p);
            }
        }

        for (Permission p : allList) {
            if (0 != p.getPId()) {
                Permission fP = pMap.get(p.getPId());

                if (fP.getPermissions() == null) {
                    fP.setPermissions(new ArrayList<Permission>());
                }

                fP.getPermissions().add(p);
            }
        }
        pMap.clear();
        pMap = null;
        return ResultInfo.success(result);
    }

    /**
     * @see com.feicheng.service.IFSystemService#getPermission(Integer) 
     */
    @Override
    public ResultInfo getPermission(Integer permissionId) {
        if (null == permissionId) {
            throw new SystemException(systemMessage.getE08());
        }

        return ResultInfo.success(iPermissionService.getById(permissionId));
    }

    /**
     * @see com.feicheng.service.IFSystemService#addPermission(Permission) 
     */
    @Override
    public ResultInfo addPermission(Permission permission) {
        if (null != permission.getPermissionId()) {
            throw new SystemException(systemMessage.getE08());
        }

        if (!StringUtils.hasLength(permission.getName())) {
            throw new SystemException(systemMessage.getE09());
        }

        if (null == permission.getPId()) {
            throw new SystemException(systemMessage.getE10());
        } else if (0 == permission.getPId()) {
            permission.setPath("");
        } else {
            if (!StringUtils.hasLength(permission.getPath())) {
                throw new SystemException(systemMessage.getE11());
            }
        }
        Integer currentUserId = super.currentUser().getUserId();
        permission.setCu(currentUserId);
        permission.setCt(super.ct(true));
        permission.setUu(currentUserId);
        permission.setUt(super.ct());
        permission.setStatu(true);

        iPermissionService.save(permission);

        return ResultInfo.success();
    }

    /**
     * @see com.feicheng.service.IFSystemService#updatePermission(Permission) 
     */
    @Override
    public ResultInfo updatePermission(Permission permission) {
        if (null == permission.getPermissionId()) {
            throw new SystemException(systemMessage.getE08());
        }

        permission.setCu(null);
        permission.setCt(null);

        int currentUserId = super.currentUser().getUserId();

        permission.setUu(currentUserId);
        permission.setUt(super.ct(true));

        if (null == permission.getPId()) {
            throw new SystemException(systemMessage.getE10());
        } else if (0 == permission.getPId()) {
            permission.setPath("");
        } else {
            if (!StringUtils.hasLength(permission.getPath())) {
                throw new SystemException(systemMessage.getE11());
            }
        }

        iPermissionService.updateById(permission);

        return ResultInfo.success();
    }

    /**
     * @see com.feicheng.service.IFSystemService#deletePermission(Integer) 
     */
    @Override
    @Transactional
    public ResultInfo deletePermission(Integer permissionId) {
        if (null == permissionId) {
            throw new SystemException(systemMessage.getE08());
        }

        QueryWrapper<RolePermission> rpWrapper = new QueryWrapper<RolePermission>();
        rpWrapper.eq(Constant.ENTITY.PERMISSION.PERMISSION_ID, permissionId);
        iRolePermissionService.remove(rpWrapper);
        iPermissionService.removeById(permissionId);

        return ResultInfo.success();
    }
}
